package org.tacticalTroopers.jme.client;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;
import org.tacticalTroopers.jme.common.message.Element;
import org.tacticalTroopers.jme.common.message.GameMap;
import org.tacticalTroopers.jme.common.message.GameState;
import org.tacticalTroopers.jme.common.message.Id;
import org.tacticalTroopers.jme.common.message.SerializationInitializer;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.network.connection.Client;
import com.jme3.network.events.MessageListener;
import com.jme3.network.message.Message;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;

public class JmeClient extends SimpleApplication {

	final static Log log = LogFactory.getLog(JmeClient.class);
	JmeClient me = this;
	
	
	
	public void simpleInitApp() {

		PropertyConfigurator.configure("log4j.properties");
		log.info("[CLIENT]");
		SerializationInitializer.init();
		Client c= new Client();
		try {
			c.connect("localhost",56650,56651);
		} catch (IllegalArgumentException e) {
			log.error(e);
		} catch (IOException e) {
			log.error(e);
		}


		c.addMessageListener(new MessageListener() {

			@Override
			public void objectSent(Object arg0) {}

			@Override
			public void objectReceived(Object arg0) {}

			@Override
			public void messageSent(Message arg0) {}

			@Override
			public void messageReceived(Message message) {
				log.info("Received Id:"+((Id)message).getValue());
			}
		},Id.class);

		c.addMessageListener(new MessageListener() {

			@Override
			public void objectSent(Object arg0) {}

			@Override
			public void objectReceived(Object arg0) {}

			@Override
			public void messageSent(Message arg0) {}

			@Override
			public void messageReceived(Message message) {
				final GameMap gm = (GameMap)message;
				log.info("Received GameMap:"+gm);
				me.enqueue(new Callable<Void>() {
					public Void call() throws Exception {
						displayGameMap(gm,rootNode);		
						return null;
					}
				});
				
				
				displayGameMap((GameMap)message, rootNode);
			}
		},GameMap.class);

		c.addMessageListener(new MessageListener() {

			@Override
			public void objectSent(Object arg0) {}

			@Override
			public void objectReceived(Object arg0) {}

			@Override
			public void messageSent(Message arg0) {}

			@Override
			public void messageReceived(Message message) {
				final GameState gs=(GameState)message;
				log.info("Received GameState:"+gs);

				me.enqueue(new Callable<Void>() {
					public Void call() throws Exception {
						displayGameState(gs,rootNode);		
						return null;
					}
				});



			}
		},GameState.class);

		c.start();
		
		

	}




	Map<Integer,Node> nodes = new HashMap<Integer,Node>();

	void displayGameState(GameState gs,Node rootNode){
		for(Integer id : gs.getDynamicElements().keySet()){
			Element e = gs.getDynamicElements().get(id);

			Node current = nodes.get(id);
			if(current==null){
				Vector3f size = e.getSize();
				Box box1 = new Box( new Vector3f(), size.x,size.y,size.z);
				Geometry blue = new Geometry("Box", box1);
				Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
				mat1.setColor("m_Color", ColorRGBA.Red);
				blue.setMaterial(mat1);
				Node n= new Node();
				n.attachChild(blue);
				n.setLocalTranslation(e.getPosition());
				rootNode.attachChild(n);
				nodes.put(e.getId().getValue(),n);
			}else{
				current.setLocalTranslation(e.getPosition());
			}


		}
	}


	void displayGameMap(GameMap gm,Node rootNode){
		for(Element wall : gm.getWalls()){
			Vector3f size = wall.getSize();
			Box box1 = new Box( new Vector3f(), size.x,size.y,size.z);
			Geometry blue = new Geometry("Box", box1);
			Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
			if(wall.getId().getValue()==1){
				mat1.setColor("m_Color", ColorRGBA.White);

			}else{
				mat1.setColor("m_Color", ColorRGBA.Blue);
			}
			blue.setMaterial(mat1);

			Node n= new Node();
			n.attachChild(blue);
			n.setLocalTranslation(wall.getPosition());
			rootNode.attachChild(n);
			nodes.put(wall.getId().getValue(),n);

			rootNode.attachChild(n);
		}
	}

	public static void main(String[] args) {
		new JmeClient().start();
	}


}
